{高手进}这个方法为什么会打印出(线程名+sell tickets:0)来

来源:百度知道 编辑:UC知道 时间:2024/05/30 05:42:57
class TicketsSystem
{
public static void main(String[] args)
{
SellThread st=new SellThread();
new Thread(st).start();
try
{
Thread.sleep(1);
}
catch(Exception e)
{
e.printStackTrace();
}
st.b=true;
new Thread(st).start();
}
}
class SellThread implements Runnable
{
int tickets=10;
Object obj=new Object();
boolean b=false;
public void run()
{
if(b==false)
{
while(true)
sell();
}
else
{
while(true)
{
synchronized(obj)
{
try
{
Thread.sleep(10);
}
catch(Exception e)
{
e.printStackTrace();
}
if(tickets>0)
{
System.out.println("obj:"+Thread.currentThread().getName()+
" sell tickets:"+tickets);
tickets--;
}
}
}
}
}
public synchronized void sell()

public static void main(String[] args) {
SellThread st = new SellThread();
new Thread(st).start(); //开启Thread-0线程,对sell() 操作
try {
Thread.sleep(1);
} catch (Exception e) {
e.printStackTrace();
}
st.b = true;
new Thread(st).start(); //开启Thread-1线程,对synchronized (obj){...}同步块里操作
}
===========================================
注意上面的注释
main()方法开启了两个线程买票,Thread-0线程对sell() 操作
Thread-1线程对synchronized (obj){...}同步块里操作
而sell()方法前面有synchronized修饰,
所以Thread-0线程对sell() 操作时独占对象级别的锁,Thread-1线程堵塞,无法操作
但是Thread-1线程对synchronized (obj){...}同步块里操作obj与SellThread类无关
所以Thread-1线程对synchronized (obj){...}同步块里操作时,Thread-0线程同样可以对sell() 操作
这就是为什么最后还打印出(线程名+sell tickets:0)的原因
当obj:Thread-1 sell tickets:1 即Thread-1买剩1张票时
Thread-0线程同样可以对sell() 操作,当时Thread-1判断到tickets>0还没有来得及tickets--,Thread-0同时判断
tickets>0,这样就出现了